package com.ternnetwork.core.notice.service.impl;

import com.ternnetwork.commons.model.http.BaseResponse;
import com.ternnetwork.core.accesscontroll.entity.User;
import com.ternnetwork.core.accesscontroll.service.UserService;
import com.ternnetwork.core.notice.dto.NoticeCategoryDto;
import com.ternnetwork.core.notice.entity.NoticeCategory;
import com.ternnetwork.core.notice.enums.messages.NoticeCategoryMessages;
import com.ternnetwork.core.notice.repository.NoticeCategoryRepository;
import com.ternnetwork.core.notice.repository.NoticeRepository;
import com.ternnetwork.core.notice.service.NoticeCategoryService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.Optional;

@Service
public class NoticeCategoryServiceImpl implements NoticeCategoryService {


    private final NoticeCategoryRepository noticeCategoryRepository;

    private final UserService userService;

    private final NoticeRepository noticeRepository;

    public NoticeCategoryServiceImpl(NoticeCategoryRepository noticeCategoryRepository, UserService userService, NoticeRepository noticeRepository) {
        this.noticeCategoryRepository = noticeCategoryRepository;
        this.userService = userService;
        this.noticeRepository = noticeRepository;
    }

    @Transactional(propagation = Propagation.REQUIRES_NEW,rollbackFor=Exception.class)
    public BaseResponse add(NoticeCategoryDto dto, String username){

        BaseResponse  baseResponse=checkProperties(dto);

        if(baseResponse.getStatus().intValue()==0) {

            return baseResponse;
        }

        User loginUser=userService.findByName(username);

        long totalCount=noticeCategoryRepository.getCountByNameAndParentId(dto.getName(),dto.getParentId());

        if(totalCount>0L) {
            baseResponse.setFailed(NoticeCategoryMessages.FAILED_MESSAGE_NAME_CAN_NOT_BE_DUPLICATE.getName());
            return baseResponse;
        }

        NoticeCategory noticeCategory=new NoticeCategory();

        noticeCategory.setName(dto.getName());
        noticeCategory.setParentId(dto.getParentId());
        noticeCategory.setCreatedById(loginUser.getId());

        noticeCategoryRepository.saveAndFlush(noticeCategory);

        baseResponse.setSccucess();

        return baseResponse;
    }

    @Transactional(propagation = Propagation.REQUIRES_NEW,rollbackFor=Exception.class)
    public BaseResponse update(NoticeCategoryDto dto, String username){

        BaseResponse  baseResponse=checkProperties(dto);

        if(baseResponse.getStatus().intValue()==0) {

            return baseResponse;
        }

        Optional<NoticeCategory> optional=noticeCategoryRepository.findById(dto.getId());

        if(optional.equals(Optional.empty())){

            baseResponse.setFailedForObjectNotExist();

            return baseResponse;
        }
        NoticeCategory noticeCategory=optional.get();


        long totalCount=noticeCategoryRepository.getCountByNameAndParentIdAndExcludeId(dto.getName(),dto.getParentId(),dto.getParentId());

        if(totalCount>0L) {
            baseResponse.setFailed(NoticeCategoryMessages.FAILED_MESSAGE_NAME_CAN_NOT_BE_DUPLICATE.getName());
            return baseResponse;
        }

        BeanUtils.copyProperties(dto,noticeCategory);

        noticeCategoryRepository.saveAndFlush(noticeCategory);

        baseResponse.setSccucess();

        return baseResponse;
    }


    @Transactional(propagation = Propagation.REQUIRES_NEW,rollbackFor=Exception.class)
    public BaseResponse deleteById(Long id,String username){

        BaseResponse  baseResponse=new BaseResponse();

        Optional<NoticeCategory> optional=noticeCategoryRepository.findById(id);

        if(optional.equals(Optional.empty())){

            baseResponse.setFailedForObjectNotExist();

            return baseResponse;
        }
        NoticeCategory noticeCategory=optional.get();

        long totalCount=noticeCategoryRepository.getCountByParentId(id);

        if(totalCount>0L) {
            baseResponse.setFailed(NoticeCategoryMessages.FAILED_MESSAGE_CAN_NOT_DELETE_FOR_IT_HAS_CHILDREN.getName());
            return baseResponse;
        }

        noticeRepository.updateByDeleteCategory(id);

        noticeCategoryRepository.delete(noticeCategory);

        baseResponse.setSccucess();

        return baseResponse;
    }


    public BaseResponse findAll() {

        BaseResponse baseResponse = new BaseResponse();

        List<NoticeCategory> noticeCategoryList=noticeCategoryRepository.findAll();

        baseResponse.setSccucess(noticeCategoryList);

        return baseResponse;

    }


    private BaseResponse checkProperties (NoticeCategoryDto t) {

        BaseResponse  baseResponse=new BaseResponse();

        if(StringUtils.isEmpty(t.getName())) {

            baseResponse.setFailed(NoticeCategoryMessages.FAILED_MESSAGE_NAME_CAN_NOT_BE_EMPTY.getName());

            return baseResponse;
        }

        baseResponse.setSccucess();

        return baseResponse;
    }
}
